package com.ghc.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.jwt.crypto.sign.MacSigner;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

@Configuration
@EnableResourceServer
@EnableWebSecurity  //开启web访问安全
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    //jwt签名秘钥
    private final String sign_key = "ghc123";

    @Autowired
    private GhcAccessTokenConvertor ghcAccessTokenConvertor;
    /**
     * 该方法用于定义资源服务器向远程认证服务器发起请求， 进行token校验
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        // 设置当前资源服务的资源id
//        resources.resourceId("autodeliver");
        //定义token服务对象 （token的校验就应该靠token服务对象）
        /*RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
        //校验端点、接口设置
        remoteTokenServices.setCheckTokenEndpointUrl("http://127.0.0.1:9999/oauth/check_token");
        //携带客户端id和客户端安全码
        remoteTokenServices.setClientId("client_ghc");
        remoteTokenServices.setClientSecret("abcdefg");

        resources.tokenServices(remoteTokenServices);*/
        // jwt令牌改造
        //无状态设置
        resources.resourceId("autodeliver").tokenStore(tokenStore()).stateless(true);
    }




    /**
     * 场景： 一个服务中可能有很多资源 （api）
     *   某些api 需要先认证 才能访问
     *   某些api 不需要认证  开放
     *   在当前configure方法中完成  设置是否需要经过认证
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {

        http
                //   设置session的创建策略， （根据需要创建）
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .and()
                .authorizeRequests()
                .antMatchers("/autodeliver/**").authenticated()  //autodeliver为前缀的需要验证
                .antMatchers("/demo/**").authenticated()  // demo为开头的请求需要验证
                .anyRequest().permitAll();  //其他请求不认证

    }


    /**
     * 该方法用于床架tokenStore对象 （令牌储存对象）
     token以什么形式储存
     */
    public TokenStore tokenStore(){
//        return new InMemoryTokenStore();
        //使用jwt令牌储存数据
        return new JwtTokenStore(jwtAccessTokenConverter());
    }
    /**
     * 返回juw令牌转换器， （帮助我们生成jwt令牌）
     * 在这里我们可以把签名秘钥传进去给转换器对象
     * @return
     */
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        jwtAccessTokenConverter.setSigningKey(sign_key);   //签名秘钥
        jwtAccessTokenConverter.setVerifier(new MacSigner(sign_key));   //验证时使用的秘钥， 和签名秘钥保持一致
        jwtAccessTokenConverter.setAccessTokenConverter(ghcAccessTokenConvertor);
        return jwtAccessTokenConverter;
    }
}
